package yhao.infra.feature.alipay.core;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.*;
import com.alipay.api.internal.util.AlipaySignature;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import yhao.infra.common.util.CommonDateUtil;
import yhao.infra.feature.alipay.ConfigFactory;
import yhao.infra.feature.alipay.core.callback.AliPayCallBackResult;
import yhao.infra.feature.alipay.core.config.AliPayConfig;

import java.util.HashMap;
import java.util.Map;

public class AliPayService {
    private Logger logger = LoggerFactory.getLogger(ConfigFactory.LOGGER_NAME);
    private AlipayClient alipayClient;
    private AliPayConfig alipayConfig;

    public AliPayService(AliPayConfig config) {
        this.alipayConfig = config;
        this.alipayClient = new DefaultAlipayClient(config.getGateWay(),
                config.getAppId(), config.getPrivateKey(), "json",
                config.getCharset(), config.getPublicKey(), config.getSignType());
    }

    protected AlipayClient getAlipayClient() {
        return alipayClient;
    }

    protected AliPayConfig getAlipayConfig() {
        return alipayConfig;
    }

    public <T extends AlipayResponse> T doRequest(AlipayRequest<T> request) throws AlipayApiException {
        return alipayClient.execute(request);
    }

    public <T extends AlipayResponse> T doPageRequest(AlipayRequest<T> request) throws AlipayApiException {
        return alipayClient.pageExecute(request);
    }

    public <T extends AlipayResponse> T doSdkRequest(AlipayRequest<T> request) throws AlipayApiException {
        return alipayClient.sdkExecute(request);
    }

    public static boolean isRefundCallBack(Map<String, String[]> requestParams) {
        return requestParams.containsKey("refund_fee");
    }

    /**
     * 支付宝支付异步通知
     * @see <a href="https://docs.open.alipay.com/270/105902/">更多细节</a>
     */
    public AliPayCallBackResult payCallBackCheck(Map<String, String[]> requestParams) {
        //获取支付宝POST过来反馈信息
        Map<String, String> params = new HashMap<>();
        for (String name : requestParams.keySet()) {
            String[] values = requestParams.get(name);
            String valueStr = StringUtils.join(values,",");
            //乱码解决，这段代码在出现乱码时使用。
            //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }

        logger.info("支付宝支付回调返回---->" + JSONObject.toJSONString(params));
        AliPayCallBackResult result = new AliPayCallBackResult();
        try {
            result.setSignSuccess(AlipaySignature.rsaCheckV1(params,
                    alipayConfig.getPublicKey(), alipayConfig.getCharset(), alipayConfig.getSignType()));
        } catch (AlipayApiException e) {
            logger.error("alipay支付回调验签出错!", e);
            result.setSignSuccess(false);
            return result;
        }
        result.setOut_trade_no(params.get("out_trade_no"));
        result.setTrade_no(params.get("trade_no"));
        result.setApp_id(params.get("app_id"));
        result.setTotal_amount(Double.parseDouble(params.get("total_amount")));
        result.setSeller_id(params.get("seller_id"));
        result.setBuyer_id(params.get("buyer_id"));
        result.setNotify_time(CommonDateUtil.formatStringToDate(
                params.get("notify_time"),"yyyy-MM-dd HH:mm:ss"));
        if(params.containsKey("gmt_payment")){
            result.setGmt_payment(CommonDateUtil.formatStringToDate(
                    params.get("gmt_payment"),"yyyy-MM-dd HH:mm:ss"));
        }
        if ("TRADE_SUCCESS".equals(params.get("trade_status")) || "TRADE_FINISHED".equals(params.get("trade_status"))) {
            result.setPaySuccess(true);
        } else {
            result.setPaySuccess(false);
        }
        return result;
    }
}
